package com.example.mapperapi.util;


import com.alibaba.fastjson.JSON;
import com.example.mapperapi.annotation.*;
import com.example.mapperapi.mapperMethod.DefaultMapperMethod;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;

import static cn.hutool.core.bean.BeanUtil.isEmpty;

/**
 * 低代码映射工具
 * 基本包装类型->基本包装类型,
 * 单选列表获取name值
 * javaBean->javaBean转换
 * List<E> -> List<E> 转换
 *
 * @author 徐鑫
 * @date 2023/03/24
 */
@Slf4j
public class MapperUtil {
    private static final String regex = "^[+-]?(\\d|([1-9]\\d+))(\\.\\d+)?$";
    private static final Set<Class<?>> baseClassSet;

    static {
        baseClassSet = new HashSet<>();
        baseClassSet.add(Integer.class);
        baseClassSet.add(String.class);
        baseClassSet.add(Double.class);
        baseClassSet.add(Long.class);
    }

    /**
     * 集合映射器
     */
    public static <T> List<T> mapperList(List<?> sourceList, Class<T> targetClass) {
        if (sourceList == null || targetClass == null) {
            return null;
        }
        if (sourceList.isEmpty()) {
            return Collections.emptyList();
        }
        List<T> targetList = new ArrayList<>();
        try {
            Constructor<T> declaredConstructor = targetClass.getDeclaredConstructor();
            declaredConstructor.setAccessible(true);
            T newInstance;
            for (int i = 0; i < sourceList.size(); i++) {
                if (sourceList.get(i) == null) {
                    continue;
                }
                try {
                    newInstance = declaredConstructor.newInstance();
                    mapperObject(sourceList.get(i), newInstance);
                    if (!isEmpty(newInstance)) {
                        targetList.add(newInstance);
                    }
                } catch (Exception e) {
                    log.error(e.getMessage());
                    log.error("MapperListError:第{}个 -> {}", i, targetClass);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return targetList;
    }

    /**
     * 基本类型映射器
     *
     * @param source 源
     * @param target 目标
     */
    public static void mapperBaseType(Object source, Object target) {
        BeanUtil.baseTypeCopyToBaseType(source, target);
    }


    /**
     * 对象映射器
     *
     * @param source 源
     * @param target 目标
     * @throws Exception 异常
     */
    public static void mapperObject(Object source, Object target) {
        if (source == null || target == null) {
            return;
        }
        if (isCollectionType(source) || isCollectionType(target)) {
            return;
        }
        if (baseClassSet.contains(source.getClass()) || baseClassSet.contains(target.getClass())) {
            return;
        }
        try {
            Map<String, Object> sourceMap = new HashMap<>();
            for (Field field : source.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                if (field.get(source) != null) {
                    sourceMap.put(field.getName(), field.get(source));
                }
            }
            if (sourceMap.isEmpty()) {
                return;
            }
            Class<? extends Function<Object, Object>> methodClass;
            for (Field targetField : target.getClass().getDeclaredFields()) {
                targetField.setAccessible(true);
                if (targetField.get(target) != null) {
                    continue;
                }
                if (targetField.isAnnotationPresent(MapperField.class)) {
                    methodClass = targetField.getAnnotation(MapperField.class).method();
                    if (methodClass.equals(DefaultMapperMethod.class)) {
                        if (targetField.isAnnotationPresent(DateTimeFormat.class)) {
                            doMapperDateTime(
                                    target,
                                    sourceMap.get(targetField.getAnnotation(MapperField.class).value()),
                                    targetField
                            );
                        } else if (targetField.isAnnotationPresent(TimeStampFormat.class)) {
                            doMapperTimeStamp(
                                    target,
                                    sourceMap.get(targetField.getAnnotation(MapperField.class).value()),
                                    targetField
                            );
                        } else {
                            doMapperField(
                                    target,
                                    sourceMap.get(targetField.getAnnotation(MapperField.class).value()),
                                    targetField
                            );
                        }
                    } else {
                        doDefinitionMapperMethod(
                                sourceMap.get(targetField.getAnnotation(MapperField.class).value()),
                                target,
                                targetField,
                                methodClass,
                                MapperField.class
                        );
                    }
                } else if (targetField.isAnnotationPresent(MapperSingleList.class)) {
                    methodClass = targetField.getAnnotation(MapperSingleList.class).method();
                    if (methodClass.equals(DefaultMapperMethod.class)) {
                        doMapperSingleList(target, sourceMap, targetField);
                    } else {
                        doDefinitionMapperMethod(
                                sourceMap.get(targetField.getAnnotation(MapperSingleList.class).value()),
                                target,
                                targetField,
                                methodClass,
                                MapperSingleList.class
                        );
                    }
                } else if (targetField.isAnnotationPresent(MapperObjectField.class)) {
                    doMapperObject(target, sourceMap, targetField);
                } else if (targetField.isAnnotationPresent(MapperListField.class)) {
                    doMapperList(
                            sourceMap.get(targetField.getAnnotation(MapperListField.class).value()),
                            target,
                            targetField
                    );
                } else if (targetField.isAnnotationPresent(MapperObjectFieldInSource.class)) {
                    doMapperObjectInFields(source, target, targetField);
                } else if (targetField.isAnnotationPresent(MapperFieldInObject.class)) {
                    doMapperFieldInObject(sourceMap, target, targetField);
                } else if (targetField.isAnnotationPresent(MapperFieldInMap.class)) {
                    doMapperFieldInMap(sourceMap, target, targetField);
                } else if (targetField.isAnnotationPresent(MapperFileString.class)) {
                    doMapperFileString(sourceMap, target, targetField);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    /**
     * 从被映射Map（value）中找到映射字段targetName赋值给对应添加@MapperFieldInObject的字段
     * <p>
     * value:对应的映射map字段名
     * targetName：对应map中的key
     *
     * @param sourceMap   源图
     * @param target      目标
     * @param targetField 目标字段
     */
    private static void doMapperFieldInMap(Map<String, Object> sourceMap, Object target, Field targetField) {
        String value = targetField.getAnnotation(MapperFieldInMap.class).value();
        String targetName = targetField.getAnnotation(MapperFieldInMap.class).targetName();
        Object o = sourceMap.get(value);
        if (o == null) {
            return;
        }
        if (o instanceof Map) {
            try {
                Map map = (Map) o;
                Object o2 = ((Map<?, ?>) o).get(targetName);
                doMapperField(target, o2, targetField);
            } catch (Exception e) {
                log.error(e.getMessage());
                log.error("doMapperFieldInMapError!{}.{}->{}", value, targetName, targetField.getName());
            }
        }
    }

    /**
     * 从被映射对象value中找到映射字段targetName赋值给对应添加@MapperFieldInObject的字段
     *
     * @param sourceMap   源图
     * @param target      目标
     * @param targetField 目标字段
     */
    private static void doMapperFieldInObject(Map<String, Object> sourceMap, Object target, Field targetField) {
        String value = targetField.getAnnotation(MapperFieldInObject.class).value();
        String targetName = targetField.getAnnotation(MapperFieldInObject.class).targetName();
        Object o = sourceMap.get(value);
        if (o == null) {
            return;
        }
        if (baseClassSet.contains(o) || isCollectionType(o)) {
            return;
        }
        try {
            Field declaredField = o.getClass().getDeclaredField(targetName);
            declaredField.setAccessible(true);
            Object o1 = declaredField.get(o);
            doMapperField(target, o1, targetField);
        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("doMapperFileString!{}.{}->{}", value, targetName, targetField.getName());
        }
    }


    /**
     * * 映射文件字符串
     * * 当被映射字段是String并且为url地址
     * * 则默认get请求访问url,下载资源并转为byte[]
     *
     * @param sourceMap   源
     * @param target      目标
     * @param targetField 目标字段
     */
    private static void doMapperFileString(Map<String, Object> sourceMap, Object target, Field targetField) {
        Class<?> type = targetField.getType();
        if (String.class.equals(type) || byte[].class.equals(type)) {
            String value = targetField.getAnnotation(MapperFileString.class).value();
            Object o = sourceMap.get(value);
            if (o == null) {
                return;
            }
            if (o instanceof String) {
                try {
                    String s = (String) o;
                    URL url = new URL(s);
                    URLConnection urlConnection = url.openConnection();
                    HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
                    try (InputStream inputStream = httpURLConnection.getInputStream()) {
                        byte[] bytes = readInputStream(inputStream);
                        if (String.class.equals(type)) {
                            String string = Base64.encodeBase64String(bytes);
                            targetField.set(target, string);
                        } else {
                            targetField.set(target, bytes);
                        }
                    }
                } catch (Exception e) {
                    log.error(e.getMessage());
                    log.error("doMapperFileString!{}->{}", targetField.getAnnotation(MapperFileString.class).value(), targetField.getName());
                }
            }
        }
    }

    /**
     * 读取输入流,获取byte[]
     *
     * @param inputStream 输入流
     * @return {@code byte[]}
     * @throws Exception 异常
     */
    public static byte[] readInputStream(InputStream inputStream) throws Exception {
        byte[] buffer = new byte[1024 * 4];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
            bos.flush();
        }
        bos.close();
        return bos.toByteArray();
    }

    /**
     * 映射字段对象的值
     *
     * @param source      源
     * @param target      目标
     * @param targetField 目标字段
     */
    private static void doMapperObjectInFields(Object source, Object target, Field targetField) {
        try {
            Class<?> type = targetField.getType();
            if (baseClassSet.contains(type)) {
                return;
            }
            Constructor<?> declaredConstructor = type.getDeclaredConstructor();
            declaredConstructor.setAccessible(true);
            Object instance = declaredConstructor.newInstance();
            mapperObject(source, instance);
            targetField.set(target, instance);
        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("doFindFieldInObjectError!{}", targetField.getName());
        }
    }

    /**
     * 时间戳注解解析
     * <p>
     * * 当字段类型为String时,value限定输出LocalDateTime字符串的格式
     * * 当字段类型为Long时,直接返回
     * * 当字段类型为LocalDateTime时,设置时区偏移量为8,返回LocalDateTime
     *
     * @param target      目标
     * @param sourceObj   源obj
     * @param targetField 目标字段
     */
    private static void doMapperTimeStamp(Object target, Object sourceObj, Field targetField) {
        if (sourceObj == null) {
            return;
        }
        String value = targetField.getAnnotation(TimeStampFormat.class).value();
        Class<?> type = targetField.getType();
        try {
            if (sourceObj instanceof Long) {
                if (Long.class.equals(type)) {
                    targetField.set(target, sourceObj);
                } else if (String.class.equals(type)) {
                    LocalDateTime localDateTime = Instant.ofEpochMilli((Long) sourceObj)
                            .atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
                    String format = localDateTime.format(DateTimeFormatter.ofPattern(value));
                    targetField.set(target, format);
                } else if (LocalDateTime.class.equals(type)) {
                    LocalDateTime localDateTime = Instant.ofEpochMilli((Long) sourceObj)
                            .atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
                    targetField.set(target, localDateTime);
                }
            } else if (sourceObj instanceof String) {
                Long l = 0L;
                BeanUtil.copyToLong(sourceObj, l);
                doMapperTimeStamp(target, l, targetField);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("doMapperTimeStampError!:{}->{}", targetField.getAnnotation(MapperField.class).value(), targetField.getName());
        }
    }

    /**
     * 日期时间注解解析
     * <p>
     * * 支持LocalDateTime字符串（1）->LocalDateTime字符串（2）
     * * from : 限定DateTime字符串（1）格式
     * * to   : 限定DateTime字符串（2）格式
     * *
     * * 同时支持LocalDateTime字符串（1）——>LocalDateTime
     * * 同时支持LocalDateTime字符串（1）——>Long 时间戳
     * * 此时只需要填写from限定DateTime字符串（1）格式,to为任意即可
     * *
     * * 支持LocalDateTime -> LocalDateTime字符串(to限定格式)
     * * 支持LocalDateTime -> LocalDateTime
     * * 支持LocalDateTime -> Long 时间戳
     *
     * @param target      目标
     * @param targetField 目标字段
     * @param sourceObj   源obj
     */
    private static void doMapperDateTime(Object target, Object sourceObj, Field targetField) {
        if (sourceObj == null) {
            return;
        }
        String from = targetField.getAnnotation(DateTimeFormat.class).from();
        String to = targetField.getAnnotation(DateTimeFormat.class).to();
        Class<?> type = targetField.getType();
        try {
            if (sourceObj instanceof String) {
                LocalDateTime parse = LocalDateTime.parse((String) sourceObj, DateTimeFormatter.ofPattern(from));
                if (String.class.equals(type)) {
                    String format = parse.format(DateTimeFormatter.ofPattern(to));
                    targetField.set(target, format);
                } else if (LocalDateTime.class.equals(type)) {
                    targetField.set(target, parse);
                } else if (Long.class.equals(type)) {
                    long l = parse.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
                    targetField.set(target, l);
                }
            } else if (sourceObj instanceof LocalDateTime) {
                if (LocalDateTime.class.equals(type)) {
                    targetField.set(target, sourceObj);
                } else if (String.class.equals(type)) {
                    String format = ((LocalDateTime) sourceObj).format(DateTimeFormatter.ofPattern(to));
                    targetField.set(target, format);
                } else if (Long.class.equals(type)) {
                    long l = ((LocalDateTime) sourceObj).toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
                    targetField.set(target, l);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("doMapperDateTimeError!:{}->{}", targetField.getAnnotation(MapperField.class).value(), targetField.getName());
        }
    }

    /**
     * 做自定义映射方法
     * 可用于@MapperField和@MapperSingleList上
     * 优先级最大,处理后不会再执行其他逻辑操作
     * <p>
     * 注解@MapperField:
     * 调用实现Function接口的apply方法,将返回值赋给对应字段
     * <p>
     * 注解@MapperField:
     * 先将json字符串转换为map,再根据注解中定义的mapValue取出对应值
     * 调用实现Function接口的apply方法,将返回值赋给对应字段
     *
     * @param source          源
     * @param target          目标
     * @param targetField     目标字段
     * @param functionClass   函数类
     * @param annotationClass 注释类
     */
    private static void doDefinitionMapperMethod(Object source, Object target, Field targetField, Class<?> functionClass, Class<?> annotationClass) {
        if (MapperSingleList.class.equals(annotationClass)) {
            try {
                if (source != null) {
                    String string = source.toString();
                    String mapValue = targetField.getAnnotation(MapperSingleList.class).mapValue();
                    string = JSON.parseObject(string, Map.class).get(mapValue).toString();
                    Constructor<?> constructor = functionClass.getDeclaredConstructor();
                    Object newInstance = constructor.newInstance();
                    Method apply = functionClass.getMethod("apply", Object.class);
                    Object invoke = apply.invoke(newInstance, string);
                    targetField.set(target, invoke);
                }
            } catch (Exception e) {
                log.error(e.getMessage());
                log.error("MapperSingleListError:{} -> {}!", targetField.getAnnotation(MapperSingleList.class).value(), targetField.getName());
            }
        } else if (MapperField.class.equals(annotationClass)) {
            try {
                Constructor<?> constructor = functionClass.getDeclaredConstructor();
                Object newInstance = constructor.newInstance();
                Method apply = functionClass.getMethod("apply", Object.class);
                Object invoke = apply.invoke(newInstance, source);
                targetField.set(target, invoke);
            } catch (Exception e) {
                log.error(e.getMessage());
                log.error("doDefinitionMapperMethodError:{} -> {}!", targetField.getAnnotation(MapperField.class).value(), targetField.getName());
            }
        }

    }

    /**
     * 做映射器列表
     *
     * @param source      源
     * @param target      目标
     * @param targetField 目标字段
     */
    private static void doMapperList(Object source, Object target, Field targetField) {
        try {
            Class<?> objectType = targetField.getAnnotation(MapperListField.class).objectType();
            if (source instanceof List) {
                List list = mapperList((List) source, objectType);
                targetField.set(target, list);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("MapperListError:{} -> {}!", targetField.getAnnotation(MapperListField.class).value(), targetField.getName());
        }
    }


    /**
     * 做映射器列表(已过时)
     *
     * @param target      目标
     * @param sourceMap   源图
     * @param targetField 目标字段
     */
    @Deprecated
    private static void doMapperList(Object target, Map<String, Object> sourceMap, Field targetField) {
        Object sourceObj;
        sourceObj = sourceMap.get(targetField.getAnnotation(MapperListField.class).value());
        if (sourceObj instanceof List) {
            List<Object> sourceList = (List) sourceObj;
            if (sourceList.size() > 0) {
                try {
                    List<Object> list = new ArrayList<>();
                    Object newInstance;
                    Class<?> aClass = targetField.getAnnotation(MapperListField.class).objectType();
                    Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
                    declaredConstructor.setAccessible(true);
                    for (Object o1 : sourceList) {
                        newInstance = declaredConstructor.newInstance();
                        mapperObject(o1, newInstance);
                        if (!isEmpty(newInstance)) {
                            list.add(newInstance);
                        }
                    }
                    targetField.set(target, list);
                } catch (Exception e) {
                    log.error(e.getMessage());
                    log.error("MapperListError:{} -> {}!", targetField.getAnnotation(MapperListField.class).value(), targetField.getName());
                }
            }
        }
    }

    /**
     * 做映射对象
     *
     * @param target      目标
     * @param sourceMap   源图
     * @param targetField 目标字段
     * @throws Exception 异常
     */
    private static void doMapperObject(Object target, Map<String, Object> sourceMap, Field targetField) {
        Object sourceObj;
        sourceObj = sourceMap.get(targetField.getAnnotation(MapperObjectField.class).value());
        if (
                sourceObj != null
        ) {
            try {
                Constructor<?> declaredConstructor = targetField.getType().getDeclaredConstructor();
                declaredConstructor.setAccessible(true);
                Object newInstance = declaredConstructor.newInstance();
                mapperObject(sourceMap.get(targetField.getAnnotation(MapperObjectField.class).value()), newInstance);
                if (!isEmpty(newInstance)) {
                    targetField.set(target, newInstance);
                }
            } catch (Exception e) {
                log.error(e.getMessage());
                log.error("MapperObjectError:{} -> {}!", targetField.getAnnotation(MapperObjectField.class).value(), targetField.getName());
            }
        }
    }

    /**
     * 做映射器单选列表
     *
     * @param target      目标
     * @param sourceMap   源图
     * @param targetField 目标字段
     */
    private static void doMapperSingleList(Object target, Map<String, Object> sourceMap, Field targetField) {
        Object o = sourceMap.get(targetField.getAnnotation(MapperSingleList.class).value());
        try {
            if (o != null) {
                String string = o.toString();
                String mapValue = targetField.getAnnotation(MapperSingleList.class).mapValue();
                string = JSON.parseObject(string, Map.class).get(mapValue).toString();
                targetField.set(target, string);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("MapperSingleListError:{} -> {}!", targetField.getAnnotation(MapperSingleList.class).value(), targetField.getName());
        }
    }

    /**
     * 做映射字段
     *
     * @param target      目标
     * @param targetField 目标字段
     * @param sourceObj   源obj
     */
    private static void doMapperField(Object target, Object sourceObj, Field targetField) {
        Class<?> type = targetField.getType();
        if (sourceObj != null
                &&
                baseClassSet.contains(type)
                &&
                baseClassSet.contains(sourceObj.getClass())
        ) {
            try {
                Class<?> aClass = sourceObj.getClass();
                int precision;
                boolean force;
                if (targetField.isAnnotationPresent(MapperField.class)) {
                    precision = targetField.getAnnotation(MapperField.class).precision();
                    force = targetField.getAnnotation(MapperField.class).force();
                } else if (targetField.isAnnotationPresent(MapperFieldInObject.class)) {
                    precision = targetField.getAnnotation(MapperFieldInObject.class).precision();
                    force = targetField.getAnnotation(MapperFieldInObject.class).force();
                } else if (targetField.isAnnotationPresent(MapperFieldInMap.class)) {
                    precision = targetField.getAnnotation(MapperFieldInMap.class).precision();
                    force = targetField.getAnnotation(MapperFieldInMap.class).force();
                } else {
                    return;
                }
                if (force) {
                    if (String.class.equals(type)) {
                        if (Integer.class.equals(aClass)) {
                            double v = BigDecimal.valueOf(((Integer) sourceObj).doubleValue())
                                    .setScale(precision, RoundingMode.HALF_UP)
                                    .doubleValue();
                            targetField.set(target, String.valueOf(v));
                        } else if (Double.class.equals(aClass)) {
                            double v = BigDecimal.valueOf(((Double) sourceObj))
                                    .setScale(precision, RoundingMode.HALF_UP)
                                    .doubleValue();
                            targetField.set(target, String.valueOf(v));
                        } else if (Long.class.equals(aClass)) {
                            double v = BigDecimal.valueOf(((Long) sourceObj))
                                    .setScale(precision, RoundingMode.HALF_UP)
                                    .doubleValue();
                            targetField.set(target, String.valueOf(v));
                        } else if (String.class.equals(aClass)) {
                            if (((String) sourceObj).matches(regex)) {
                                try {
                                    String[] split = ((String) sourceObj).split("[.]");
                                    switch (split[1].length()) {
                                        case 2:
                                            targetField.set(target, split[0] + split[1] + "0");
                                            break;
                                        case 3:
                                            targetField.set(target, split[0] + split[1]);
                                            break;
                                        default:
                                            targetField.set(target, split[0] + split[1].substring(0, 3));
                                    }
                                } catch (Exception e) {
                                    targetField.set(target, Long.parseLong((String) sourceObj));
                                }
                            } else {
                                targetField.set(target, sourceObj);
                            }
                        }
                    }
                    doExcludeStringMapper(sourceObj, target, targetField, precision);

                } else {
                    if (String.class.equals(type)) {
                        targetField.set(target, sourceObj.toString());
                    }
                    doExcludeStringMapper(sourceObj, target, targetField, precision);
                }
            } catch (Exception e) {
                log.error(e.getMessage());
                log.error("MapperFieldError:{}!", targetField.getName());
            }
        }
    }

    /**
     * 做除了字符串其他类型映射
     *
     * @param sourceObj   源obj
     * @param target      目标
     * @param targetField 目标字段
     * @param precision   精度
     */
    private static void doExcludeStringMapper(Object sourceObj, Object target, Field targetField, int precision) {
        try {
            Class<?> type = targetField.getType();
            Class<?> aClass = sourceObj.getClass();
            if (Integer.class.equals(type)) {
                Double value = Double.parseDouble(String.valueOf(sourceObj));
                if (value > Integer.MAX_VALUE) {
                    return;
                }
                targetField.set(target, value.intValue());
            } else if (Double.class.equals(type)) {
                if (String.class.equals(aClass)) {
                    double v = BigDecimal.valueOf(Double.parseDouble((String) sourceObj))
                            .setScale(precision, RoundingMode.HALF_UP)
                            .doubleValue();
                    targetField.set(target, v);
                } else if (Long.class.equals(aClass)) {
                    double v = BigDecimal.valueOf((Long) sourceObj)
                            .setScale(precision, RoundingMode.HALF_UP)
                            .doubleValue();
                    targetField.set(target, v);
                } else if (Integer.class.equals(aClass)) {
                    double v = BigDecimal.valueOf(((Integer) sourceObj).doubleValue())
                            .setScale(precision, RoundingMode.HALF_UP)
                            .doubleValue();
                    targetField.set(target, v);
                } else if (Double.class.equals(aClass)) {
                    double v = BigDecimal.valueOf(((Double) sourceObj))
                            .setScale(precision, RoundingMode.HALF_UP)
                            .doubleValue();
                    targetField.set(target, v);
                }
            } else if (Long.class.equals(type)) {
                if (String.class.equals(aClass)) {
                    if (((String) sourceObj).matches(regex)) {
                        try {
                            String[] split = ((String) sourceObj).split("[.]");
                            targetField.set(target, Long.parseLong(split[0]));
                        } catch (Exception e) {
                            targetField.set(target, Long.parseLong((String) sourceObj));
                        }
                    }
                } else if (Long.class.equals(aClass)) {
                    targetField.set(target, sourceObj);
                } else if (Integer.class.equals(aClass)) {
                    targetField.set(target, ((Integer) sourceObj).longValue());
                } else if (Double.class.equals(aClass)) {
                    BigDecimal bigDecimal = BigDecimal.valueOf((Double) sourceObj);
                    targetField.set(target, bigDecimal.longValue());
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("doExcludeStringMapperError:{} -> {}!", targetField.getAnnotation(MapperField.class).value(), targetField.getName());
        }

    }

    /**
     * 判断是否是集合类型(Map,List,Set)
     *
     * @param o o
     */
    public static boolean isCollectionType(Object o) {
        if (o != null) {
            if (o instanceof Map) {
                return true;
            } else if (o instanceof Set) {
                return true;
            } else return o instanceof List;
        }
        return false;
    }

    /**
     * 判断是否是基本包装类型(String,Integer,Double,Long)
     *
     * @param o o
     * @return boolean
     */
    public static boolean isBaseType(Object o) {
        if (o != null) {
            if (o instanceof String) {
                return true;
            } else if (o instanceof Double) {
                return true;
            } else if (o instanceof Integer) {
                return true;
            } else return o instanceof Long;
        }
        return false;
    }


}
